import { AxiosError } from 'axios'
import { exeStrategyActions } from '@/utils'
import { Api } from '@/typings/request'
import {
    DEFAULT_REQUEST_ERROR_CODE,
    DEFAULT_REQUEST_ERROR_MSG,
    ERROR_STATUS,
    NETWORK_ERROR_CODE,
    NETWORK_ERROR_MSG,
    REQUEST_TIMEOUT_CODE,
    REQUEST_TIMEOUT_MSG
} from '@/utils/request/constant'

/**
 * 处理请求错误
 * @param error
 */
function handleApiError(error: AxiosError): Api.Result {
    const resultError: Api.Error = {
        type: 'axios',
        code: DEFAULT_REQUEST_ERROR_CODE,
        msg: DEFAULT_REQUEST_ERROR_MSG
    }

    const actions: Common.StrategyAction[] = [
        [
            // 网路错误
            !window.navigator.onLine || error.message === 'Network Error',
            () => {
                Object.assign(resultError, {
                    code: NETWORK_ERROR_CODE,
                    msg: NETWORK_ERROR_MSG
                })
            }
        ],
        [
            // 超时错误
            error.code === REQUEST_TIMEOUT_CODE && error.message.includes('timeout'),
            () => {
                Object.assign(resultError, {
                    code: REQUEST_TIMEOUT_CODE,
                    msg: REQUEST_TIMEOUT_MSG
                })
            }
        ],
        [
            // 请求不成功的错误
            Boolean(error.response),
            () => {
                const errorCode: Api.ErrorStatus =
                    (error.response?.status as Api.ErrorStatus) || 'DEFAULT'
                const msg = ERROR_STATUS[errorCode]
                Object.assign(resultError, { code: errorCode, msg })
            }
        ]
    ]

    exeStrategyActions(actions)

    return { error: resultError, result: null }
}

/**
 * 处理异常，包括请求发起失败和 响应
 * @param error
 */
export function handleError(error: any): Api.Result {
    let result: Api.Result
    if (error instanceof AxiosError) {
        result = handleApiError(error)
    } else {
        result = {
            error: {
                type: 'axios',
                code: DEFAULT_REQUEST_ERROR_CODE,
                msg: DEFAULT_REQUEST_ERROR_MSG
            },
            result: null
        }
    }
    return result
}
